// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.

using System;
using System.Globalization;
using System.Numerics;
using System.Runtime.CompilerServices;

using Microsoft.Scripting.Runtime;
using Microsoft.Scripting.Utils;

using IronPython.Runtime.Types;

#pragma warning disable 675

namespace IronPython.Runtime.Operations {

    #region Generated IntOps

    // *** BEGIN GENERATED CODE ***
    // generated by function: gen_int from: generate_alltypes.py

    public static partial class SByteOps {

        #region Constructors

        [StaticExtensionMethod]
        public static object __new__(PythonType cls) {
            return __new__(cls, default(SByte));
        }

        [StaticExtensionMethod]
        public static object __new__(PythonType cls, object value) {
            if (cls != DynamicHelpers.GetPythonTypeFromType(typeof(SByte))) {
                throw PythonOps.TypeError("SByte.__new__: first argument must be SByte type.");
            }
            if (value is IConvertible valueConvertible) {
                switch (valueConvertible.GetTypeCode()) {
                    case TypeCode.Byte:   return checked((SByte)(Byte)value);
                    case TypeCode.SByte:  return checked((SByte)(SByte)value);
                    case TypeCode.Int16:  return checked((SByte)(Int16)value);
                    case TypeCode.UInt16: return checked((SByte)(UInt16)value);
                    case TypeCode.Int32:  return checked((SByte)(Int32)value);
                    case TypeCode.UInt32: return checked((SByte)(UInt32)value);
                    case TypeCode.Int64:  return checked((SByte)(Int64)value);
                    case TypeCode.UInt64: return checked((SByte)(UInt64)value);
                    case TypeCode.Single: return checked((SByte)(Single)value);
                    case TypeCode.Double: return checked((SByte)(Double)value);
                }
            }
            if (value is String s) {
                try {
                    return SByte.Parse(s, System.Globalization.NumberFormatInfo.InvariantInfo);
                } catch (FormatException ex) {
                    throw PythonOps.ValueError("{0}", ex.Message);
                }
            } else if (value is BigInteger bi) {
                return checked((SByte)bi);
            } else if (value is Extensible<BigInteger> ebi) {
                return checked((SByte)ebi.Value);
            } else if (value is Extensible<double> ed) {
                return checked((SByte)ed.Value);
            }
            throw PythonOps.TypeError("can't convert {0} to SByte", PythonOps.GetPythonTypeName(value));
        }

        #endregion

        #region Unary Operations

        [SpecialName]
        public static SByte Plus(SByte x) => x;

        [SpecialName]
        public static object Negate(SByte x) {
            if (x == SByte.MinValue) return -(Int16)SByte.MinValue;
            else return (SByte)(-x);
        }

        [SpecialName]
        public static object Abs(SByte x) {
            if (x < 0) {
                if (x == SByte.MinValue) return -(Int16)SByte.MinValue;
                else return (SByte)(-x);
            } else {
                return x;
            }
        }

        [SpecialName]
        public static SByte OnesComplement(SByte x) => (SByte)(~(x));

        public static bool __bool__(SByte x) => (x != 0);

        public static string __repr__(SByte x) => x.ToString(CultureInfo.InvariantCulture);

        public static SByte __trunc__(SByte x) => x;

        public static int __int__(SByte x) => unchecked((int)x);

        public static int __index__(SByte x) => unchecked((int)x);

        public static int __hash__(SByte x) {
            if (x == -1) return -2;
            return unchecked((int)x);
        }

        #endregion

        #region Binary Operations - Arithmetic

        [SpecialName]
        public static object Add(SByte x, SByte y) {
            Int16 result = (Int16)(((Int16)x) + ((Int16)y));
            if (SByte.MinValue <= result && result <= SByte.MaxValue) {
                return (SByte)(result);
            } else {
                return result;
            }
        }

        [SpecialName]
        public static object Subtract(SByte x, SByte y) {
            Int16 result = (Int16)(((Int16)x) - ((Int16)y));
            if (SByte.MinValue <= result && result <= SByte.MaxValue) {
                return (SByte)(result);
            } else {
                return result;
            }
        }

        [SpecialName]
        public static object Multiply(SByte x, SByte y) {
            Int16 result = (Int16)(((Int16)x) * ((Int16)y));
            if (SByte.MinValue <= result && result <= SByte.MaxValue) {
                return (SByte)(result);
            } else {
                return result;
            }
        }

        [SpecialName]
        public static double TrueDivide(SByte x, SByte y) {
            return DoubleOps.TrueDivide((double)x, (double)y);
        }

        [SpecialName]
        public static object FloorDivide(SByte x, SByte y) {
            if (y == -1 && x == SByte.MinValue) {
                return -(Int16)SByte.MinValue;
            } else {
                return (SByte)MathUtils.FloorDivideUnchecked(x, y);
            }
        }

        [SpecialName]
        public static SByte Mod(SByte x, SByte y) {
            return (SByte)Int32Ops.Mod((Int32)x, (Int32)y);
        }

        [SpecialName]
        public static object Power(SByte x, SByte y) {
            return Int32Ops.Power((Int32)x, (Int32)y);
        }

        #endregion

        #region Binary Operations - Bitwise

        [SpecialName]
        public static object LeftShift(SByte x, BigInteger y) {
            return BigIntegerOps.LeftShift((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static SByte RightShift(SByte x, BigInteger y) {
            return (SByte)BigIntegerOps.RightShift((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static object LeftShift(SByte x, Int32 y) {
            return Int32Ops.LeftShift((Int32)x, (Int32)y);
        }

        [SpecialName]
        public static SByte RightShift(SByte x, Int32 y) {
            return (SByte)Int32Ops.RightShift((Int32)x, (Int32)y);
        }

        [SpecialName]
        public static SByte BitwiseAnd(SByte x, SByte y) {
            return (SByte)(x & y);
        }

        [SpecialName]
        public static SByte BitwiseOr(SByte x, SByte y) {
            return (SByte)(x | y);
        }

        [SpecialName]
        public static SByte ExclusiveOr(SByte x, SByte y) {
            return (SByte)(x ^ y);
        }

        #endregion

        #region Binary Operations - Comparisons

        [SpecialName]
        public static bool LessThan(SByte x, SByte y) => x < y;
        [SpecialName]
        public static bool LessThanOrEqual(SByte x, SByte y) => x <= y;
        [SpecialName]
        public static bool GreaterThan(SByte x, SByte y) => x > y;
        [SpecialName]
        public static bool GreaterThanOrEqual(SByte x, SByte y) => x >= y;
        [SpecialName]
        public static bool Equals(SByte x, SByte y) => x == y;
        [SpecialName]
        public static bool NotEquals(SByte x, SByte y) => x != y;

        #endregion

        #region Conversion operators

        [SpecialName, ExplicitConversionMethod]
        public static Byte ConvertToByte(SByte x) {
            if (x >= 0) {
                return (Byte)x;
            }
            throw Converter.CannotConvertOverflow("Byte", x);
        }

        [SpecialName, ImplicitConversionMethod]
        public static Int16 ConvertToInt16(SByte x) => (Int16)x;

        [SpecialName, ExplicitConversionMethod]
        public static UInt16 ConvertToUInt16(SByte x) {
            if (x >= 0) {
                return (UInt16)x;
            }
            throw Converter.CannotConvertOverflow("UInt16", x);
        }

        [SpecialName, ImplicitConversionMethod]
        public static Int32 ConvertToInt32(SByte x) => (Int32)x;

        [SpecialName, ExplicitConversionMethod]
        public static UInt32 ConvertToUInt32(SByte x) {
            if (x >= 0) {
                return (UInt32)x;
            }
            throw Converter.CannotConvertOverflow("UInt32", x);
        }

        [SpecialName, ImplicitConversionMethod]
        public static Int64 ConvertToInt64(SByte x) => (Int64)x;

        [SpecialName, ExplicitConversionMethod]
        public static UInt64 ConvertToUInt64(SByte x) {
            if (x >= 0) {
                return (UInt64)x;
            }
            throw Converter.CannotConvertOverflow("UInt64", x);
        }

        [SpecialName, ImplicitConversionMethod]
        public static Single ConvertToSingle(SByte x) => (Single)x;

        [SpecialName, ImplicitConversionMethod]
        public static Double ConvertToDouble(SByte x) => (Double)x;

        #endregion

        #region Public API - Numerics

        [PropertyMethod, SpecialName]
        public static SByte Getreal(SByte x) => x;

        [PropertyMethod, SpecialName]
        public static SByte Getimag(SByte x) => (SByte)0;

        public static SByte conjugate(SByte x) => x;


        [PropertyMethod, SpecialName]
        public static SByte Getnumerator(SByte x) => x;

        [PropertyMethod, SpecialName]
        public static SByte Getdenominator(SByte x) => (SByte)1;

        public static int bit_length(SByte value) {
            return MathUtils.BitLength((int)value);
        }

        public static Bytes to_bytes(SByte value, int length, [NotNone] string byteorder, bool signed = false) {
            // TODO: signed should be a keyword only argument
            return Int64Ops.to_bytes(value, length, byteorder, signed);
        }

        #endregion
    }

    public static partial class ByteOps {

        #region Constructors

        [StaticExtensionMethod]
        public static object __new__(PythonType cls) {
            return __new__(cls, default(Byte));
        }

        [StaticExtensionMethod]
        public static object __new__(PythonType cls, object value) {
            if (cls != DynamicHelpers.GetPythonTypeFromType(typeof(Byte))) {
                throw PythonOps.TypeError("Byte.__new__: first argument must be Byte type.");
            }
            if (value is IConvertible valueConvertible) {
                switch (valueConvertible.GetTypeCode()) {
                    case TypeCode.Byte:   return checked((Byte)(Byte)value);
                    case TypeCode.SByte:  return checked((Byte)(SByte)value);
                    case TypeCode.Int16:  return checked((Byte)(Int16)value);
                    case TypeCode.UInt16: return checked((Byte)(UInt16)value);
                    case TypeCode.Int32:  return checked((Byte)(Int32)value);
                    case TypeCode.UInt32: return checked((Byte)(UInt32)value);
                    case TypeCode.Int64:  return checked((Byte)(Int64)value);
                    case TypeCode.UInt64: return checked((Byte)(UInt64)value);
                    case TypeCode.Single: return checked((Byte)(Single)value);
                    case TypeCode.Double: return checked((Byte)(Double)value);
                }
            }
            if (value is String s) {
                try {
                    return Byte.Parse(s, System.Globalization.NumberFormatInfo.InvariantInfo);
                } catch (FormatException ex) {
                    throw PythonOps.ValueError("{0}", ex.Message);
                }
            } else if (value is BigInteger bi) {
                return checked((Byte)bi);
            } else if (value is Extensible<BigInteger> ebi) {
                return checked((Byte)ebi.Value);
            } else if (value is Extensible<double> ed) {
                return checked((Byte)ed.Value);
            }
            throw PythonOps.TypeError("can't convert {0} to Byte", PythonOps.GetPythonTypeName(value));
        }

        #endregion

        #region Unary Operations

        [SpecialName]
        public static Byte Plus(Byte x) => x;

        [SpecialName]
        public static object Negate(Byte x) => Int16Ops.Negate((Int16)x);

        [SpecialName]
        public static Byte Abs(Byte x) => x;

        [SpecialName]
        public static object OnesComplement(Byte x) => Int16Ops.OnesComplement((Int16)x);

        public static bool __bool__(Byte x) => (x != 0);

        public static string __repr__(Byte x) => x.ToString(CultureInfo.InvariantCulture);

        public static Byte __trunc__(Byte x) => x;

        public static int __int__(Byte x) => unchecked((int)x);

        public static int __index__(Byte x) => unchecked((int)x);

        public static int __hash__(Byte x) {
            return unchecked((int)x);
        }

        #endregion

        #region Binary Operations - Arithmetic

        [SpecialName]
        public static object Add(Byte x, Byte y) {
            Int16 result = (Int16)(((Int16)x) + ((Int16)y));
            if (Byte.MinValue <= result && result <= Byte.MaxValue) {
                return (Byte)(result);
            } else {
                return result;
            }
        }

        [SpecialName]
        public static object Add(Byte x, SByte y) {
            return Int16Ops.Add((Int16)x, (Int16)y);
        }

        [SpecialName]
        public static object Add(SByte x, Byte y) {
            return Int16Ops.Add((Int16)x, (Int16)y);
        }

        [SpecialName]
        public static object Subtract(Byte x, Byte y) {
            Int16 result = (Int16)(((Int16)x) - ((Int16)y));
            if (Byte.MinValue <= result && result <= Byte.MaxValue) {
                return (Byte)(result);
            } else {
                return result;
            }
        }

        [SpecialName]
        public static object Subtract(Byte x, SByte y) {
            return Int16Ops.Subtract((Int16)x, (Int16)y);
        }

        [SpecialName]
        public static object Subtract(SByte x, Byte y) {
            return Int16Ops.Subtract((Int16)x, (Int16)y);
        }

        [SpecialName]
        public static object Multiply(Byte x, Byte y) {
            Int16 result = (Int16)(((Int16)x) * ((Int16)y));
            if (Byte.MinValue <= result && result <= Byte.MaxValue) {
                return (Byte)(result);
            } else {
                return result;
            }
        }

        [SpecialName]
        public static object Multiply(Byte x, SByte y) {
            return Int16Ops.Multiply((Int16)x, (Int16)y);
        }

        [SpecialName]
        public static object Multiply(SByte x, Byte y) {
            return Int16Ops.Multiply((Int16)x, (Int16)y);
        }

        [SpecialName]
        public static double TrueDivide(Byte x, Byte y) {
            return DoubleOps.TrueDivide((double)x, (double)y);
        }

        [SpecialName]
        public static double TrueDivide(Byte x, SByte y) {
            return Int16Ops.TrueDivide((Int16)x, (Int16)y);
        }

        [SpecialName]
        public static double TrueDivide(SByte x, Byte y) {
            return Int16Ops.TrueDivide((Int16)x, (Int16)y);
        }

        [SpecialName]
        public static Byte FloorDivide(Byte x, Byte y) {
            return (Byte)(x / y);
        }

        [SpecialName]
        public static object FloorDivide(Byte x, SByte y) {
            return Int16Ops.FloorDivide((Int16)x, (Int16)y);
        }

        [SpecialName]
        public static object FloorDivide(SByte x, Byte y) {
            return Int16Ops.FloorDivide((Int16)x, (Int16)y);
        }

        [SpecialName]
        public static Byte Mod(Byte x, Byte y) {
            return (Byte)(x % y);
        }

        [SpecialName]
        public static Int16 Mod(Byte x, SByte y) {
            return Int16Ops.Mod((Int16)x, (Int16)y);
        }

        [SpecialName]
        public static Int16 Mod(SByte x, Byte y) {
            return Int16Ops.Mod((Int16)x, (Int16)y);
        }

        [SpecialName]
        public static object Power(Byte x, Byte y) {
            return Int32Ops.Power((Int32)x, (Int32)y);
        }

        [SpecialName]
        public static object Power(Byte x, SByte y) {
            return Int16Ops.Power((Int16)x, (Int16)y);
        }

        [SpecialName]
        public static object Power(SByte x, Byte y) {
            return Int16Ops.Power((Int16)x, (Int16)y);
        }

        #endregion

        #region Binary Operations - Bitwise

        [SpecialName]
        public static object LeftShift(Byte x, BigInteger y) {
            return BigIntegerOps.LeftShift((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static Byte RightShift(Byte x, BigInteger y) {
            return (Byte)BigIntegerOps.RightShift((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static object LeftShift(Byte x, Int32 y) {
            return Int32Ops.LeftShift((Int32)x, (Int32)y);
        }

        [SpecialName]
        public static Byte RightShift(Byte x, Int32 y) {
            return (Byte)Int32Ops.RightShift((Int32)x, (Int32)y);
        }

        [SpecialName]
        public static Byte BitwiseAnd(Byte x, Byte y) {
            return (Byte)(x & y);
        }

        [SpecialName]
        public static Int16 BitwiseAnd(Byte x, SByte y) {
            return Int16Ops.BitwiseAnd((Int16)x, (Int16)y);
        }

        [SpecialName]
        public static Int16 BitwiseAnd(SByte x, Byte y) {
            return Int16Ops.BitwiseAnd((Int16)x, (Int16)y);
        }

        [SpecialName]
        public static Byte BitwiseOr(Byte x, Byte y) {
            return (Byte)(x | y);
        }

        [SpecialName]
        public static Int16 BitwiseOr(Byte x, SByte y) {
            return Int16Ops.BitwiseOr((Int16)x, (Int16)y);
        }

        [SpecialName]
        public static Int16 BitwiseOr(SByte x, Byte y) {
            return Int16Ops.BitwiseOr((Int16)x, (Int16)y);
        }

        [SpecialName]
        public static Byte ExclusiveOr(Byte x, Byte y) {
            return (Byte)(x ^ y);
        }

        [SpecialName]
        public static Int16 ExclusiveOr(Byte x, SByte y) {
            return Int16Ops.ExclusiveOr((Int16)x, (Int16)y);
        }

        [SpecialName]
        public static Int16 ExclusiveOr(SByte x, Byte y) {
            return Int16Ops.ExclusiveOr((Int16)x, (Int16)y);
        }

        #endregion

        #region Binary Operations - Comparisons

        [SpecialName]
        public static bool LessThan(Byte x, Byte y) => x < y;
        [SpecialName]
        public static bool LessThan(Byte x, SByte y) => x < y;
        [SpecialName]
        public static bool LessThanOrEqual(Byte x, Byte y) => x <= y;
        [SpecialName]
        public static bool LessThanOrEqual(Byte x, SByte y) => x <= y;
        [SpecialName]
        public static bool GreaterThan(Byte x, Byte y) => x > y;
        [SpecialName]
        public static bool GreaterThan(Byte x, SByte y) => x > y;
        [SpecialName]
        public static bool GreaterThanOrEqual(Byte x, Byte y) => x >= y;
        [SpecialName]
        public static bool GreaterThanOrEqual(Byte x, SByte y) => x >= y;
        [SpecialName]
        public static bool Equals(Byte x, Byte y) => x == y;
        [SpecialName]
        public static bool Equals(Byte x, SByte y) => x == y;
        [SpecialName]
        public static bool NotEquals(Byte x, Byte y) => x != y;
        [SpecialName]
        public static bool NotEquals(Byte x, SByte y) => x != y;

        #endregion

        #region Conversion operators

        [SpecialName, ExplicitConversionMethod]
        public static SByte ConvertToSByte(Byte x) {
            if (x <= (Byte)SByte.MaxValue) {
                return (SByte)x;
            }
            throw Converter.CannotConvertOverflow("SByte", x);
        }

        [SpecialName, ImplicitConversionMethod]
        public static Int16 ConvertToInt16(Byte x) => (Int16)x;

        [SpecialName, ImplicitConversionMethod]
        public static UInt16 ConvertToUInt16(Byte x) => (UInt16)x;

        [SpecialName, ImplicitConversionMethod]
        public static Int32 ConvertToInt32(Byte x) => (Int32)x;

        [SpecialName, ImplicitConversionMethod]
        public static UInt32 ConvertToUInt32(Byte x) => (UInt32)x;

        [SpecialName, ImplicitConversionMethod]
        public static Int64 ConvertToInt64(Byte x) => (Int64)x;

        [SpecialName, ImplicitConversionMethod]
        public static UInt64 ConvertToUInt64(Byte x) => (UInt64)x;

        [SpecialName, ImplicitConversionMethod]
        public static Single ConvertToSingle(Byte x) => (Single)x;

        [SpecialName, ImplicitConversionMethod]
        public static Double ConvertToDouble(Byte x) => (Double)x;

        #endregion

        #region Public API - Numerics

        [PropertyMethod, SpecialName]
        public static Byte Getreal(Byte x) => x;

        [PropertyMethod, SpecialName]
        public static Byte Getimag(Byte x) => (Byte)0;

        public static Byte conjugate(Byte x) => x;


        [PropertyMethod, SpecialName]
        public static Byte Getnumerator(Byte x) => x;

        [PropertyMethod, SpecialName]
        public static Byte Getdenominator(Byte x) => (Byte)1;

        public static int bit_length(Byte value) {
            return MathUtils.BitLength((int)value);
        }

        public static Bytes to_bytes(Byte value, int length, [NotNone] string byteorder, bool signed = false) {
            // TODO: signed should be a keyword only argument
            return UInt64Ops.to_bytes(value, length, byteorder, signed);
        }

        #endregion
    }

    public static partial class Int16Ops {

        #region Constructors

        [StaticExtensionMethod]
        public static object __new__(PythonType cls) {
            return __new__(cls, default(Int16));
        }

        [StaticExtensionMethod]
        public static object __new__(PythonType cls, object value) {
            if (cls != DynamicHelpers.GetPythonTypeFromType(typeof(Int16))) {
                throw PythonOps.TypeError("Int16.__new__: first argument must be Int16 type.");
            }
            if (value is IConvertible valueConvertible) {
                switch (valueConvertible.GetTypeCode()) {
                    case TypeCode.Byte:   return checked((Int16)(Byte)value);
                    case TypeCode.SByte:  return checked((Int16)(SByte)value);
                    case TypeCode.Int16:  return checked((Int16)(Int16)value);
                    case TypeCode.UInt16: return checked((Int16)(UInt16)value);
                    case TypeCode.Int32:  return checked((Int16)(Int32)value);
                    case TypeCode.UInt32: return checked((Int16)(UInt32)value);
                    case TypeCode.Int64:  return checked((Int16)(Int64)value);
                    case TypeCode.UInt64: return checked((Int16)(UInt64)value);
                    case TypeCode.Single: return checked((Int16)(Single)value);
                    case TypeCode.Double: return checked((Int16)(Double)value);
                }
            }
            if (value is String s) {
                try {
                    return Int16.Parse(s, System.Globalization.NumberFormatInfo.InvariantInfo);
                } catch (FormatException ex) {
                    throw PythonOps.ValueError("{0}", ex.Message);
                }
            } else if (value is BigInteger bi) {
                return checked((Int16)bi);
            } else if (value is Extensible<BigInteger> ebi) {
                return checked((Int16)ebi.Value);
            } else if (value is Extensible<double> ed) {
                return checked((Int16)ed.Value);
            }
            throw PythonOps.TypeError("can't convert {0} to Int16", PythonOps.GetPythonTypeName(value));
        }

        #endregion

        #region Unary Operations

        [SpecialName]
        public static Int16 Plus(Int16 x) => x;

        [SpecialName]
        public static object Negate(Int16 x) {
            if (x == Int16.MinValue) return -(Int32)Int16.MinValue;
            else return (Int16)(-x);
        }

        [SpecialName]
        public static object Abs(Int16 x) {
            if (x < 0) {
                if (x == Int16.MinValue) return -(Int32)Int16.MinValue;
                else return (Int16)(-x);
            } else {
                return x;
            }
        }

        [SpecialName]
        public static Int16 OnesComplement(Int16 x) => (Int16)(~(x));

        public static bool __bool__(Int16 x) => (x != 0);

        public static string __repr__(Int16 x) => x.ToString(CultureInfo.InvariantCulture);

        public static Int16 __trunc__(Int16 x) => x;

        public static int __int__(Int16 x) => unchecked((int)x);

        public static int __index__(Int16 x) => unchecked((int)x);

        public static int __hash__(Int16 x) {
            if (x == -1) return -2;
            return unchecked((int)x);
        }

        #endregion

        #region Binary Operations - Arithmetic

        [SpecialName]
        public static object Add(Int16 x, Int16 y) {
            Int32 result = (Int32)(((Int32)x) + ((Int32)y));
            if (Int16.MinValue <= result && result <= Int16.MaxValue) {
                return (Int16)(result);
            } else {
                return result;
            }
        }

        [SpecialName]
        public static object Subtract(Int16 x, Int16 y) {
            Int32 result = (Int32)(((Int32)x) - ((Int32)y));
            if (Int16.MinValue <= result && result <= Int16.MaxValue) {
                return (Int16)(result);
            } else {
                return result;
            }
        }

        [SpecialName]
        public static object Multiply(Int16 x, Int16 y) {
            Int32 result = (Int32)(((Int32)x) * ((Int32)y));
            if (Int16.MinValue <= result && result <= Int16.MaxValue) {
                return (Int16)(result);
            } else {
                return result;
            }
        }

        [SpecialName]
        public static double TrueDivide(Int16 x, Int16 y) {
            return DoubleOps.TrueDivide((double)x, (double)y);
        }

        [SpecialName]
        public static object FloorDivide(Int16 x, Int16 y) {
            if (y == -1 && x == Int16.MinValue) {
                return -(Int32)Int16.MinValue;
            } else {
                return (Int16)MathUtils.FloorDivideUnchecked(x, y);
            }
        }

        [SpecialName]
        public static Int16 Mod(Int16 x, Int16 y) {
            return (Int16)Int32Ops.Mod((Int32)x, (Int32)y);
        }

        [SpecialName]
        public static object Power(Int16 x, Int16 y) {
            return Int32Ops.Power((Int32)x, (Int32)y);
        }

        #endregion

        #region Binary Operations - Bitwise

        [SpecialName]
        public static object LeftShift(Int16 x, BigInteger y) {
            return BigIntegerOps.LeftShift((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static Int16 RightShift(Int16 x, BigInteger y) {
            return (Int16)BigIntegerOps.RightShift((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static object LeftShift(Int16 x, Int32 y) {
            return Int32Ops.LeftShift((Int32)x, (Int32)y);
        }

        [SpecialName]
        public static Int16 RightShift(Int16 x, Int32 y) {
            return (Int16)Int32Ops.RightShift((Int32)x, (Int32)y);
        }

        [SpecialName]
        public static Int16 BitwiseAnd(Int16 x, Int16 y) {
            return (Int16)(x & y);
        }

        [SpecialName]
        public static Int16 BitwiseOr(Int16 x, Int16 y) {
            return (Int16)(x | y);
        }

        [SpecialName]
        public static Int16 ExclusiveOr(Int16 x, Int16 y) {
            return (Int16)(x ^ y);
        }

        #endregion

        #region Binary Operations - Comparisons

        [SpecialName]
        public static bool LessThan(Int16 x, Int16 y) => x < y;
        [SpecialName]
        public static bool LessThanOrEqual(Int16 x, Int16 y) => x <= y;
        [SpecialName]
        public static bool GreaterThan(Int16 x, Int16 y) => x > y;
        [SpecialName]
        public static bool GreaterThanOrEqual(Int16 x, Int16 y) => x >= y;
        [SpecialName]
        public static bool Equals(Int16 x, Int16 y) => x == y;
        [SpecialName]
        public static bool NotEquals(Int16 x, Int16 y) => x != y;

        #endregion

        #region Conversion operators

        [SpecialName, ExplicitConversionMethod]
        public static SByte ConvertToSByte(Int16 x) {
            if (SByte.MinValue <= x && x <= SByte.MaxValue) {
                return (SByte)x;
            }
            throw Converter.CannotConvertOverflow("SByte", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static Byte ConvertToByte(Int16 x) {
            if (Byte.MinValue <= x && x <= Byte.MaxValue) {
                return (Byte)x;
            }
            throw Converter.CannotConvertOverflow("Byte", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static UInt16 ConvertToUInt16(Int16 x) {
            if (x >= 0) {
                return (UInt16)x;
            }
            throw Converter.CannotConvertOverflow("UInt16", x);
        }

        [SpecialName, ImplicitConversionMethod]
        public static Int32 ConvertToInt32(Int16 x) => (Int32)x;

        [SpecialName, ExplicitConversionMethod]
        public static UInt32 ConvertToUInt32(Int16 x) {
            if (x >= 0) {
                return (UInt32)x;
            }
            throw Converter.CannotConvertOverflow("UInt32", x);
        }

        [SpecialName, ImplicitConversionMethod]
        public static Int64 ConvertToInt64(Int16 x) => (Int64)x;

        [SpecialName, ExplicitConversionMethod]
        public static UInt64 ConvertToUInt64(Int16 x) {
            if (x >= 0) {
                return (UInt64)x;
            }
            throw Converter.CannotConvertOverflow("UInt64", x);
        }

        [SpecialName, ImplicitConversionMethod]
        public static Single ConvertToSingle(Int16 x) => (Single)x;

        [SpecialName, ImplicitConversionMethod]
        public static Double ConvertToDouble(Int16 x) => (Double)x;

        #endregion

        #region Public API - Numerics

        [PropertyMethod, SpecialName]
        public static Int16 Getreal(Int16 x) => x;

        [PropertyMethod, SpecialName]
        public static Int16 Getimag(Int16 x) => (Int16)0;

        public static Int16 conjugate(Int16 x) => x;


        [PropertyMethod, SpecialName]
        public static Int16 Getnumerator(Int16 x) => x;

        [PropertyMethod, SpecialName]
        public static Int16 Getdenominator(Int16 x) => (Int16)1;

        public static int bit_length(Int16 value) {
            return MathUtils.BitLength((int)value);
        }

        public static Bytes to_bytes(Int16 value, int length, [NotNone] string byteorder, bool signed = false) {
            // TODO: signed should be a keyword only argument
            return Int64Ops.to_bytes(value, length, byteorder, signed);
        }

        #endregion
    }

    public static partial class UInt16Ops {

        #region Constructors

        [StaticExtensionMethod]
        public static object __new__(PythonType cls) {
            return __new__(cls, default(UInt16));
        }

        [StaticExtensionMethod]
        public static object __new__(PythonType cls, object value) {
            if (cls != DynamicHelpers.GetPythonTypeFromType(typeof(UInt16))) {
                throw PythonOps.TypeError("UInt16.__new__: first argument must be UInt16 type.");
            }
            if (value is IConvertible valueConvertible) {
                switch (valueConvertible.GetTypeCode()) {
                    case TypeCode.Byte:   return checked((UInt16)(Byte)value);
                    case TypeCode.SByte:  return checked((UInt16)(SByte)value);
                    case TypeCode.Int16:  return checked((UInt16)(Int16)value);
                    case TypeCode.UInt16: return checked((UInt16)(UInt16)value);
                    case TypeCode.Int32:  return checked((UInt16)(Int32)value);
                    case TypeCode.UInt32: return checked((UInt16)(UInt32)value);
                    case TypeCode.Int64:  return checked((UInt16)(Int64)value);
                    case TypeCode.UInt64: return checked((UInt16)(UInt64)value);
                    case TypeCode.Single: return checked((UInt16)(Single)value);
                    case TypeCode.Double: return checked((UInt16)(Double)value);
                }
            }
            if (value is String s) {
                try {
                    return UInt16.Parse(s, System.Globalization.NumberFormatInfo.InvariantInfo);
                } catch (FormatException ex) {
                    throw PythonOps.ValueError("{0}", ex.Message);
                }
            } else if (value is BigInteger bi) {
                return checked((UInt16)bi);
            } else if (value is Extensible<BigInteger> ebi) {
                return checked((UInt16)ebi.Value);
            } else if (value is Extensible<double> ed) {
                return checked((UInt16)ed.Value);
            }
            throw PythonOps.TypeError("can't convert {0} to UInt16", PythonOps.GetPythonTypeName(value));
        }

        #endregion

        #region Unary Operations

        [SpecialName]
        public static UInt16 Plus(UInt16 x) => x;

        [SpecialName]
        public static object Negate(UInt16 x) => Int32Ops.Negate((Int32)x);

        [SpecialName]
        public static UInt16 Abs(UInt16 x) => x;

        [SpecialName]
        public static object OnesComplement(UInt16 x) => Int32Ops.OnesComplement((Int32)x);

        public static bool __bool__(UInt16 x) => (x != 0);

        public static string __repr__(UInt16 x) => x.ToString(CultureInfo.InvariantCulture);

        public static UInt16 __trunc__(UInt16 x) => x;

        public static int __int__(UInt16 x) => unchecked((int)x);

        public static int __index__(UInt16 x) => unchecked((int)x);

        public static int __hash__(UInt16 x) {
            return unchecked((int)x);
        }

        #endregion

        #region Binary Operations - Arithmetic

        [SpecialName]
        public static object Add(UInt16 x, UInt16 y) {
            Int32 result = (Int32)(((Int32)x) + ((Int32)y));
            if (UInt16.MinValue <= result && result <= UInt16.MaxValue) {
                return (UInt16)(result);
            } else {
                return result;
            }
        }

        [SpecialName]
        public static object Add(UInt16 x, Int16 y) {
            return Int32Ops.Add((Int32)x, (Int32)y);
        }

        [SpecialName]
        public static object Add(Int16 x, UInt16 y) {
            return Int32Ops.Add((Int32)x, (Int32)y);
        }

        [SpecialName]
        public static object Subtract(UInt16 x, UInt16 y) {
            Int32 result = (Int32)(((Int32)x) - ((Int32)y));
            if (UInt16.MinValue <= result && result <= UInt16.MaxValue) {
                return (UInt16)(result);
            } else {
                return result;
            }
        }

        [SpecialName]
        public static object Subtract(UInt16 x, Int16 y) {
            return Int32Ops.Subtract((Int32)x, (Int32)y);
        }

        [SpecialName]
        public static object Subtract(Int16 x, UInt16 y) {
            return Int32Ops.Subtract((Int32)x, (Int32)y);
        }

        [SpecialName]
        public static object Multiply(UInt16 x, UInt16 y) {
            Int32 result = (Int32)(((Int32)x) * ((Int32)y));
            if (UInt16.MinValue <= result && result <= UInt16.MaxValue) {
                return (UInt16)(result);
            } else {
                return result;
            }
        }

        [SpecialName]
        public static object Multiply(UInt16 x, Int16 y) {
            return Int32Ops.Multiply((Int32)x, (Int32)y);
        }

        [SpecialName]
        public static object Multiply(Int16 x, UInt16 y) {
            return Int32Ops.Multiply((Int32)x, (Int32)y);
        }

        [SpecialName]
        public static double TrueDivide(UInt16 x, UInt16 y) {
            return DoubleOps.TrueDivide((double)x, (double)y);
        }

        [SpecialName]
        public static double TrueDivide(UInt16 x, Int16 y) {
            return Int32Ops.TrueDivide((Int32)x, (Int32)y);
        }

        [SpecialName]
        public static double TrueDivide(Int16 x, UInt16 y) {
            return Int32Ops.TrueDivide((Int32)x, (Int32)y);
        }

        [SpecialName]
        public static UInt16 FloorDivide(UInt16 x, UInt16 y) {
            return (UInt16)(x / y);
        }

        [SpecialName]
        public static object FloorDivide(UInt16 x, Int16 y) {
            return Int32Ops.FloorDivide((Int32)x, (Int32)y);
        }

        [SpecialName]
        public static object FloorDivide(Int16 x, UInt16 y) {
            return Int32Ops.FloorDivide((Int32)x, (Int32)y);
        }

        [SpecialName]
        public static UInt16 Mod(UInt16 x, UInt16 y) {
            return (UInt16)(x % y);
        }

        [SpecialName]
        public static Int32 Mod(UInt16 x, Int16 y) {
            return Int32Ops.Mod((Int32)x, (Int32)y);
        }

        [SpecialName]
        public static Int32 Mod(Int16 x, UInt16 y) {
            return Int32Ops.Mod((Int32)x, (Int32)y);
        }

        [SpecialName]
        public static object Power(UInt16 x, UInt16 y) {
            return Int32Ops.Power((Int32)x, (Int32)y);
        }

        [SpecialName]
        public static object Power(UInt16 x, Int16 y) {
            return Int32Ops.Power((Int32)x, (Int32)y);
        }

        [SpecialName]
        public static object Power(Int16 x, UInt16 y) {
            return Int32Ops.Power((Int32)x, (Int32)y);
        }

        #endregion

        #region Binary Operations - Bitwise

        [SpecialName]
        public static object LeftShift(UInt16 x, BigInteger y) {
            return BigIntegerOps.LeftShift((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static UInt16 RightShift(UInt16 x, BigInteger y) {
            return (UInt16)BigIntegerOps.RightShift((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static object LeftShift(UInt16 x, Int32 y) {
            return Int32Ops.LeftShift((Int32)x, (Int32)y);
        }

        [SpecialName]
        public static UInt16 RightShift(UInt16 x, Int32 y) {
            return (UInt16)Int32Ops.RightShift((Int32)x, (Int32)y);
        }

        [SpecialName]
        public static UInt16 BitwiseAnd(UInt16 x, UInt16 y) {
            return (UInt16)(x & y);
        }

        [SpecialName]
        public static Int32 BitwiseAnd(UInt16 x, Int16 y) {
            return Int32Ops.BitwiseAnd((Int32)x, (Int32)y);
        }

        [SpecialName]
        public static Int32 BitwiseAnd(Int16 x, UInt16 y) {
            return Int32Ops.BitwiseAnd((Int32)x, (Int32)y);
        }

        [SpecialName]
        public static UInt16 BitwiseOr(UInt16 x, UInt16 y) {
            return (UInt16)(x | y);
        }

        [SpecialName]
        public static Int32 BitwiseOr(UInt16 x, Int16 y) {
            return Int32Ops.BitwiseOr((Int32)x, (Int32)y);
        }

        [SpecialName]
        public static Int32 BitwiseOr(Int16 x, UInt16 y) {
            return Int32Ops.BitwiseOr((Int32)x, (Int32)y);
        }

        [SpecialName]
        public static UInt16 ExclusiveOr(UInt16 x, UInt16 y) {
            return (UInt16)(x ^ y);
        }

        [SpecialName]
        public static Int32 ExclusiveOr(UInt16 x, Int16 y) {
            return Int32Ops.ExclusiveOr((Int32)x, (Int32)y);
        }

        [SpecialName]
        public static Int32 ExclusiveOr(Int16 x, UInt16 y) {
            return Int32Ops.ExclusiveOr((Int32)x, (Int32)y);
        }

        #endregion

        #region Binary Operations - Comparisons

        [SpecialName]
        public static bool LessThan(UInt16 x, UInt16 y) => x < y;
        [SpecialName]
        public static bool LessThan(UInt16 x, Int16 y) => x < y;
        [SpecialName]
        public static bool LessThanOrEqual(UInt16 x, UInt16 y) => x <= y;
        [SpecialName]
        public static bool LessThanOrEqual(UInt16 x, Int16 y) => x <= y;
        [SpecialName]
        public static bool GreaterThan(UInt16 x, UInt16 y) => x > y;
        [SpecialName]
        public static bool GreaterThan(UInt16 x, Int16 y) => x > y;
        [SpecialName]
        public static bool GreaterThanOrEqual(UInt16 x, UInt16 y) => x >= y;
        [SpecialName]
        public static bool GreaterThanOrEqual(UInt16 x, Int16 y) => x >= y;
        [SpecialName]
        public static bool Equals(UInt16 x, UInt16 y) => x == y;
        [SpecialName]
        public static bool Equals(UInt16 x, Int16 y) => x == y;
        [SpecialName]
        public static bool NotEquals(UInt16 x, UInt16 y) => x != y;
        [SpecialName]
        public static bool NotEquals(UInt16 x, Int16 y) => x != y;

        #endregion

        #region Conversion operators

        [SpecialName, ExplicitConversionMethod]
        public static SByte ConvertToSByte(UInt16 x) {
            if (x <= (UInt16)SByte.MaxValue) {
                return (SByte)x;
            }
            throw Converter.CannotConvertOverflow("SByte", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static Byte ConvertToByte(UInt16 x) {
            if (Byte.MinValue <= x && x <= Byte.MaxValue) {
                return (Byte)x;
            }
            throw Converter.CannotConvertOverflow("Byte", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static Int16 ConvertToInt16(UInt16 x) {
            if (x <= (UInt16)Int16.MaxValue) {
                return (Int16)x;
            }
            throw Converter.CannotConvertOverflow("Int16", x);
        }

        [SpecialName, ImplicitConversionMethod]
        public static Int32 ConvertToInt32(UInt16 x) => (Int32)x;

        [SpecialName, ImplicitConversionMethod]
        public static UInt32 ConvertToUInt32(UInt16 x) => (UInt32)x;

        [SpecialName, ImplicitConversionMethod]
        public static Int64 ConvertToInt64(UInt16 x) => (Int64)x;

        [SpecialName, ImplicitConversionMethod]
        public static UInt64 ConvertToUInt64(UInt16 x) => (UInt64)x;

        [SpecialName, ImplicitConversionMethod]
        public static Single ConvertToSingle(UInt16 x) => (Single)x;

        [SpecialName, ImplicitConversionMethod]
        public static Double ConvertToDouble(UInt16 x) => (Double)x;

        #endregion

        #region Public API - Numerics

        [PropertyMethod, SpecialName]
        public static UInt16 Getreal(UInt16 x) => x;

        [PropertyMethod, SpecialName]
        public static UInt16 Getimag(UInt16 x) => (UInt16)0;

        public static UInt16 conjugate(UInt16 x) => x;


        [PropertyMethod, SpecialName]
        public static UInt16 Getnumerator(UInt16 x) => x;

        [PropertyMethod, SpecialName]
        public static UInt16 Getdenominator(UInt16 x) => (UInt16)1;

        public static int bit_length(UInt16 value) {
            return MathUtils.BitLength((int)value);
        }

        public static Bytes to_bytes(UInt16 value, int length, [NotNone] string byteorder, bool signed = false) {
            // TODO: signed should be a keyword only argument
            return UInt64Ops.to_bytes(value, length, byteorder, signed);
        }

        #endregion
    }

    public static partial class Int32Ops {

        #region Constructors

        [StaticExtensionMethod]
        public static object __new__(PythonType cls) {
            return __new__(cls, default(Int32));
        }

        [StaticExtensionMethod]
        public static object __new__(PythonType cls, object value) {
            if (cls != DynamicHelpers.GetPythonTypeFromType(typeof(Int32))) {
                throw PythonOps.TypeError("Int32.__new__: first argument must be Int32 type.");
            }
            if (value is IConvertible valueConvertible) {
                switch (valueConvertible.GetTypeCode()) {
                    case TypeCode.Byte:   return checked((Int32)(Byte)value);
                    case TypeCode.SByte:  return checked((Int32)(SByte)value);
                    case TypeCode.Int16:  return checked((Int32)(Int16)value);
                    case TypeCode.UInt16: return checked((Int32)(UInt16)value);
                    case TypeCode.Int32:  return checked((Int32)(Int32)value);
                    case TypeCode.UInt32: return checked((Int32)(UInt32)value);
                    case TypeCode.Int64:  return checked((Int32)(Int64)value);
                    case TypeCode.UInt64: return checked((Int32)(UInt64)value);
                    case TypeCode.Single: return checked((Int32)(Single)value);
                    case TypeCode.Double: return checked((Int32)(Double)value);
                }
            }
            if (value is String s) {
                try {
                    return Int32.Parse(s, System.Globalization.NumberFormatInfo.InvariantInfo);
                } catch (FormatException ex) {
                    throw PythonOps.ValueError("{0}", ex.Message);
                }
            } else if (value is BigInteger bi) {
                return checked((Int32)bi);
            } else if (value is Extensible<BigInteger> ebi) {
                return checked((Int32)ebi.Value);
            } else if (value is Extensible<double> ed) {
                return checked((Int32)ed.Value);
            }
            throw PythonOps.TypeError("can't convert {0} to Int32", PythonOps.GetPythonTypeName(value));
        }

        #endregion

        #region Unary Operations

        [SpecialName]
        public static Int32 Plus(Int32 x) => x;

        [SpecialName]
        public static object Negate(Int32 x) {
            if (x == Int32.MinValue) return -(BigInteger)Int32.MinValue;
            else return (Int32)(-x);
        }

        [SpecialName]
        public static object Abs(Int32 x) {
            if (x < 0) {
                if (x == Int32.MinValue) return -(BigInteger)Int32.MinValue;
                else return (Int32)(-x);
            } else {
                return x;
            }
        }

        [SpecialName]
        public static Int32 OnesComplement(Int32 x) => (Int32)(~(x));

        public static bool __bool__(Int32 x) => (x != 0);

        public static string __repr__(Int32 x) => x.ToString(CultureInfo.InvariantCulture);

        public static Int32 __trunc__(Int32 x) => x;

        public static int __int__(Int32 x) => unchecked((int)x);

        public static int __index__(Int32 x) => unchecked((int)x);

        public static int __hash__(Int32 x) {
            // for perf we use an if for the 3 int values with abs(x) >= int.MaxValue
            if (x == -1 || x == int.MinValue) return -2;
            if (x == int.MaxValue || x == int.MinValue + 1) return 0;
            return unchecked((int)x);
        }

        #endregion

        #region Binary Operations - Arithmetic

        [SpecialName]
        public static object Add(Int32 x, Int32 y) {
            long result = (long)x + y;
            if (Int32.MinValue <= result && result <= Int32.MaxValue) {
                return Microsoft.Scripting.Runtime.ScriptingRuntimeHelpers.Int32ToObject((Int32)(result));
            }
            return BigIntegerOps.Add((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static object Subtract(Int32 x, Int32 y) {
            long result = (long)x - y;
            if (Int32.MinValue <= result && result <= Int32.MaxValue) {
                return Microsoft.Scripting.Runtime.ScriptingRuntimeHelpers.Int32ToObject((Int32)(result));
            }
            return BigIntegerOps.Subtract((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static object Multiply(Int32 x, Int32 y) {
            long result = (long)x * y;
            if (Int32.MinValue <= result && result <= Int32.MaxValue) {
                return Microsoft.Scripting.Runtime.ScriptingRuntimeHelpers.Int32ToObject((Int32)(result));
            }
            return BigIntegerOps.Multiply((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static double TrueDivide(Int32 x, Int32 y) {
            return DoubleOps.TrueDivide((double)x, (double)y);
        }

        #endregion

        #region Binary Operations - Bitwise

        [SpecialName]
        public static object LeftShift(Int32 x, BigInteger y) {
            return BigIntegerOps.LeftShift((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static Int32 RightShift(Int32 x, BigInteger y) {
            return (Int32)BigIntegerOps.RightShift((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static Int32 BitwiseAnd(Int32 x, Int32 y) {
            return (Int32)(x & y);
        }

        [SpecialName]
        public static Int32 BitwiseOr(Int32 x, Int32 y) {
            return (Int32)(x | y);
        }

        [SpecialName]
        public static Int32 ExclusiveOr(Int32 x, Int32 y) {
            return (Int32)(x ^ y);
        }

        #endregion

        #region Binary Operations - Comparisons

        [SpecialName]
        public static bool LessThan(Int32 x, Int32 y) => x < y;
        [SpecialName]
        public static bool LessThanOrEqual(Int32 x, Int32 y) => x <= y;
        [SpecialName]
        public static bool GreaterThan(Int32 x, Int32 y) => x > y;
        [SpecialName]
        public static bool GreaterThanOrEqual(Int32 x, Int32 y) => x >= y;
        [SpecialName]
        public static bool Equals(Int32 x, Int32 y) => x == y;
        [SpecialName]
        public static bool NotEquals(Int32 x, Int32 y) => x != y;

        #endregion

        #region Conversion operators

        [SpecialName, ExplicitConversionMethod]
        public static SByte ConvertToSByte(Int32 x) {
            if (SByte.MinValue <= x && x <= SByte.MaxValue) {
                return (SByte)x;
            }
            throw Converter.CannotConvertOverflow("SByte", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static Byte ConvertToByte(Int32 x) {
            if (Byte.MinValue <= x && x <= Byte.MaxValue) {
                return (Byte)x;
            }
            throw Converter.CannotConvertOverflow("Byte", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static Int16 ConvertToInt16(Int32 x) {
            if (Int16.MinValue <= x && x <= Int16.MaxValue) {
                return (Int16)x;
            }
            throw Converter.CannotConvertOverflow("Int16", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static UInt16 ConvertToUInt16(Int32 x) {
            if (UInt16.MinValue <= x && x <= UInt16.MaxValue) {
                return (UInt16)x;
            }
            throw Converter.CannotConvertOverflow("UInt16", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static UInt32 ConvertToUInt32(Int32 x) {
            if (x >= 0) {
                return (UInt32)x;
            }
            throw Converter.CannotConvertOverflow("UInt32", x);
        }

        [SpecialName, ImplicitConversionMethod]
        public static Int64 ConvertToInt64(Int32 x) => (Int64)x;

        [SpecialName, ExplicitConversionMethod]
        public static UInt64 ConvertToUInt64(Int32 x) {
            if (x >= 0) {
                return (UInt64)x;
            }
            throw Converter.CannotConvertOverflow("UInt64", x);
        }

        [SpecialName, ImplicitConversionMethod]
        public static Single ConvertToSingle(Int32 x) => (Single)x;

        [SpecialName, ImplicitConversionMethod]
        public static Double ConvertToDouble(Int32 x) => (Double)x;

        #endregion

        #region Public API - Numerics

        [PropertyMethod, SpecialName]
        public static Int32 Getreal(Int32 x) => x;

        [PropertyMethod, SpecialName]
        public static Int32 Getimag(Int32 x) => (Int32)0;

        public static Int32 conjugate(Int32 x) => x;


        [PropertyMethod, SpecialName]
        public static Int32 Getnumerator(Int32 x) => x;

        [PropertyMethod, SpecialName]
        public static Int32 Getdenominator(Int32 x) => (Int32)1;

        public static int bit_length(Int32 value) {
            return MathUtils.BitLength(value);
        }

        public static Bytes to_bytes(Int32 value, int length, [NotNone] string byteorder, bool signed = false) {
            // TODO: signed should be a keyword only argument
            return Int64Ops.to_bytes(value, length, byteorder, signed);
        }

        #endregion
    }

    public static partial class UInt32Ops {

        #region Constructors

        [StaticExtensionMethod]
        public static object __new__(PythonType cls) {
            return __new__(cls, default(UInt32));
        }

        [StaticExtensionMethod]
        public static object __new__(PythonType cls, object value) {
            if (cls != DynamicHelpers.GetPythonTypeFromType(typeof(UInt32))) {
                throw PythonOps.TypeError("UInt32.__new__: first argument must be UInt32 type.");
            }
            if (value is IConvertible valueConvertible) {
                switch (valueConvertible.GetTypeCode()) {
                    case TypeCode.Byte:   return checked((UInt32)(Byte)value);
                    case TypeCode.SByte:  return checked((UInt32)(SByte)value);
                    case TypeCode.Int16:  return checked((UInt32)(Int16)value);
                    case TypeCode.UInt16: return checked((UInt32)(UInt16)value);
                    case TypeCode.Int32:  return checked((UInt32)(Int32)value);
                    case TypeCode.UInt32: return checked((UInt32)(UInt32)value);
                    case TypeCode.Int64:  return checked((UInt32)(Int64)value);
                    case TypeCode.UInt64: return checked((UInt32)(UInt64)value);
                    case TypeCode.Single: return checked((UInt32)(Single)value);
                    case TypeCode.Double: return checked((UInt32)(Double)value);
                }
            }
            if (value is String s) {
                try {
                    return UInt32.Parse(s, System.Globalization.NumberFormatInfo.InvariantInfo);
                } catch (FormatException ex) {
                    throw PythonOps.ValueError("{0}", ex.Message);
                }
            } else if (value is BigInteger bi) {
                return checked((UInt32)bi);
            } else if (value is Extensible<BigInteger> ebi) {
                return checked((UInt32)ebi.Value);
            } else if (value is Extensible<double> ed) {
                return checked((UInt32)ed.Value);
            }
            throw PythonOps.TypeError("can't convert {0} to UInt32", PythonOps.GetPythonTypeName(value));
        }

        #endregion

        #region Unary Operations

        [SpecialName]
        public static UInt32 Plus(UInt32 x) => x;

        [SpecialName]
        public static object Negate(UInt32 x) => Int64Ops.Negate((Int64)x);

        [SpecialName]
        public static UInt32 Abs(UInt32 x) => x;

        [SpecialName]
        public static object OnesComplement(UInt32 x) => Int64Ops.OnesComplement((Int64)x);

        public static bool __bool__(UInt32 x) => (x != 0);

        public static string __repr__(UInt32 x) => x.ToString(CultureInfo.InvariantCulture);

        public static UInt32 __trunc__(UInt32 x) => x;

        public static BigInteger __int__(UInt32 x) => unchecked((BigInteger)x);

        public static BigInteger __index__(UInt32 x) => unchecked((BigInteger)x);

        public static int __hash__(UInt32 x) {
            return unchecked((int)((x >= int.MaxValue) ? (x % int.MaxValue) : x));
        }

        #endregion

        #region Binary Operations - Arithmetic

        [SpecialName]
        public static object Add(UInt32 x, UInt32 y) {
            Int64 result = (Int64)(((Int64)x) + ((Int64)y));
            if (UInt32.MinValue <= result && result <= UInt32.MaxValue) {
                return (UInt32)(result);
            } else {
                return result;
            }
        }

        [SpecialName]
        public static object Add(UInt32 x, Int32 y) {
            return Int64Ops.Add((Int64)x, (Int64)y);
        }

        [SpecialName]
        public static object Add(Int32 x, UInt32 y) {
            return Int64Ops.Add((Int64)x, (Int64)y);
        }

        [SpecialName]
        public static object Subtract(UInt32 x, UInt32 y) {
            Int64 result = (Int64)(((Int64)x) - ((Int64)y));
            if (UInt32.MinValue <= result && result <= UInt32.MaxValue) {
                return (UInt32)(result);
            } else {
                return result;
            }
        }

        [SpecialName]
        public static object Subtract(UInt32 x, Int32 y) {
            return Int64Ops.Subtract((Int64)x, (Int64)y);
        }

        [SpecialName]
        public static object Subtract(Int32 x, UInt32 y) {
            return Int64Ops.Subtract((Int64)x, (Int64)y);
        }

        [SpecialName]
        public static object Multiply(UInt32 x, UInt32 y) {
            Int64 result = (Int64)(((Int64)x) * ((Int64)y));
            if (UInt32.MinValue <= result && result <= UInt32.MaxValue) {
                return (UInt32)(result);
            } else {
                return result;
            }
        }

        [SpecialName]
        public static object Multiply(UInt32 x, Int32 y) {
            return Int64Ops.Multiply((Int64)x, (Int64)y);
        }

        [SpecialName]
        public static object Multiply(Int32 x, UInt32 y) {
            return Int64Ops.Multiply((Int64)x, (Int64)y);
        }

        [SpecialName]
        public static double TrueDivide(UInt32 x, UInt32 y) {
            return DoubleOps.TrueDivide((double)x, (double)y);
        }

        [SpecialName]
        public static double TrueDivide(UInt32 x, Int32 y) {
            return Int64Ops.TrueDivide((Int64)x, (Int64)y);
        }

        [SpecialName]
        public static double TrueDivide(Int32 x, UInt32 y) {
            return Int64Ops.TrueDivide((Int64)x, (Int64)y);
        }

        [SpecialName]
        public static UInt32 FloorDivide(UInt32 x, UInt32 y) {
            return (UInt32)(x / y);
        }

        [SpecialName]
        public static object FloorDivide(UInt32 x, Int32 y) {
            return Int64Ops.FloorDivide((Int64)x, (Int64)y);
        }

        [SpecialName]
        public static object FloorDivide(Int32 x, UInt32 y) {
            return Int64Ops.FloorDivide((Int64)x, (Int64)y);
        }

        [SpecialName]
        public static UInt32 Mod(UInt32 x, UInt32 y) {
            return (UInt32)(x % y);
        }

        [SpecialName]
        public static Int64 Mod(UInt32 x, Int32 y) {
            return Int64Ops.Mod((Int64)x, (Int64)y);
        }

        [SpecialName]
        public static Int64 Mod(Int32 x, UInt32 y) {
            return Int64Ops.Mod((Int64)x, (Int64)y);
        }

        [SpecialName]
        public static object Power(UInt32 x, UInt32 y) {
            return Int32Ops.Power((Int32)x, (Int32)y);
        }

        [SpecialName]
        public static object Power(UInt32 x, Int32 y) {
            return Int64Ops.Power((Int64)x, (Int64)y);
        }

        [SpecialName]
        public static object Power(Int32 x, UInt32 y) {
            return Int64Ops.Power((Int64)x, (Int64)y);
        }

        #endregion

        #region Binary Operations - Bitwise

        [SpecialName]
        public static object LeftShift(UInt32 x, BigInteger y) {
            return BigIntegerOps.LeftShift((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static UInt32 RightShift(UInt32 x, BigInteger y) {
            return (UInt32)BigIntegerOps.RightShift((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static UInt32 BitwiseAnd(UInt32 x, UInt32 y) {
            return (UInt32)(x & y);
        }

        [SpecialName]
        public static Int64 BitwiseAnd(UInt32 x, Int32 y) {
            return Int64Ops.BitwiseAnd((Int64)x, (Int64)y);
        }

        [SpecialName]
        public static Int64 BitwiseAnd(Int32 x, UInt32 y) {
            return Int64Ops.BitwiseAnd((Int64)x, (Int64)y);
        }

        [SpecialName]
        public static UInt32 BitwiseOr(UInt32 x, UInt32 y) {
            return (UInt32)(x | y);
        }

        [SpecialName]
        public static Int64 BitwiseOr(UInt32 x, Int32 y) {
            return Int64Ops.BitwiseOr((Int64)x, (Int64)y);
        }

        [SpecialName]
        public static Int64 BitwiseOr(Int32 x, UInt32 y) {
            return Int64Ops.BitwiseOr((Int64)x, (Int64)y);
        }

        [SpecialName]
        public static UInt32 ExclusiveOr(UInt32 x, UInt32 y) {
            return (UInt32)(x ^ y);
        }

        [SpecialName]
        public static Int64 ExclusiveOr(UInt32 x, Int32 y) {
            return Int64Ops.ExclusiveOr((Int64)x, (Int64)y);
        }

        [SpecialName]
        public static Int64 ExclusiveOr(Int32 x, UInt32 y) {
            return Int64Ops.ExclusiveOr((Int64)x, (Int64)y);
        }

        #endregion

        #region Binary Operations - Comparisons

        [SpecialName]
        public static bool LessThan(UInt32 x, UInt32 y) => x < y;
        [SpecialName]
        public static bool LessThan(UInt32 x, Int32 y) => x < y;
        [SpecialName]
        public static bool LessThanOrEqual(UInt32 x, UInt32 y) => x <= y;
        [SpecialName]
        public static bool LessThanOrEqual(UInt32 x, Int32 y) => x <= y;
        [SpecialName]
        public static bool GreaterThan(UInt32 x, UInt32 y) => x > y;
        [SpecialName]
        public static bool GreaterThan(UInt32 x, Int32 y) => x > y;
        [SpecialName]
        public static bool GreaterThanOrEqual(UInt32 x, UInt32 y) => x >= y;
        [SpecialName]
        public static bool GreaterThanOrEqual(UInt32 x, Int32 y) => x >= y;
        [SpecialName]
        public static bool Equals(UInt32 x, UInt32 y) => x == y;
        [SpecialName]
        public static bool Equals(UInt32 x, Int32 y) => x == y;
        [SpecialName]
        public static bool NotEquals(UInt32 x, UInt32 y) => x != y;
        [SpecialName]
        public static bool NotEquals(UInt32 x, Int32 y) => x != y;

        #endregion

        #region Conversion operators

        [SpecialName, ExplicitConversionMethod]
        public static SByte ConvertToSByte(UInt32 x) {
            if (x <= (UInt32)SByte.MaxValue) {
                return (SByte)x;
            }
            throw Converter.CannotConvertOverflow("SByte", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static Byte ConvertToByte(UInt32 x) {
            if (Byte.MinValue <= x && x <= Byte.MaxValue) {
                return (Byte)x;
            }
            throw Converter.CannotConvertOverflow("Byte", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static Int16 ConvertToInt16(UInt32 x) {
            if (x <= (UInt32)Int16.MaxValue) {
                return (Int16)x;
            }
            throw Converter.CannotConvertOverflow("Int16", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static UInt16 ConvertToUInt16(UInt32 x) {
            if (UInt16.MinValue <= x && x <= UInt16.MaxValue) {
                return (UInt16)x;
            }
            throw Converter.CannotConvertOverflow("UInt16", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static Int32 ConvertToInt32(UInt32 x) {
            if (x <= (UInt32)Int32.MaxValue) {
                return (Int32)x;
            }
            throw Converter.CannotConvertOverflow("Int32", x);
        }

        [SpecialName, ImplicitConversionMethod]
        public static Int64 ConvertToInt64(UInt32 x) => (Int64)x;

        [SpecialName, ImplicitConversionMethod]
        public static UInt64 ConvertToUInt64(UInt32 x) => (UInt64)x;

        [SpecialName, ImplicitConversionMethod]
        public static Single ConvertToSingle(UInt32 x) => (Single)x;

        [SpecialName, ImplicitConversionMethod]
        public static Double ConvertToDouble(UInt32 x) => (Double)x;

        #endregion

        #region Public API - Numerics

        [PropertyMethod, SpecialName]
        public static UInt32 Getreal(UInt32 x) => x;

        [PropertyMethod, SpecialName]
        public static UInt32 Getimag(UInt32 x) => (UInt32)0;

        public static UInt32 conjugate(UInt32 x) => x;


        [PropertyMethod, SpecialName]
        public static UInt32 Getnumerator(UInt32 x) => x;

        [PropertyMethod, SpecialName]
        public static UInt32 Getdenominator(UInt32 x) => (UInt32)1;

        public static int bit_length(UInt32 value) {
            return MathUtils.BitLengthUnsigned(value);
        }

        public static Bytes to_bytes(UInt32 value, int length, [NotNone] string byteorder, bool signed = false) {
            // TODO: signed should be a keyword only argument
            return UInt64Ops.to_bytes(value, length, byteorder, signed);
        }

        #endregion
    }

    public static partial class Int64Ops {

        #region Constructors

        [StaticExtensionMethod]
        public static object __new__(PythonType cls) {
            return __new__(cls, default(Int64));
        }

        [StaticExtensionMethod]
        public static object __new__(PythonType cls, object value) {
            if (cls != DynamicHelpers.GetPythonTypeFromType(typeof(Int64))) {
                throw PythonOps.TypeError("Int64.__new__: first argument must be Int64 type.");
            }
            if (value is IConvertible valueConvertible) {
                switch (valueConvertible.GetTypeCode()) {
                    case TypeCode.Byte:   return checked((Int64)(Byte)value);
                    case TypeCode.SByte:  return checked((Int64)(SByte)value);
                    case TypeCode.Int16:  return checked((Int64)(Int16)value);
                    case TypeCode.UInt16: return checked((Int64)(UInt16)value);
                    case TypeCode.Int32:  return checked((Int64)(Int32)value);
                    case TypeCode.UInt32: return checked((Int64)(UInt32)value);
                    case TypeCode.Int64:  return checked((Int64)(Int64)value);
                    case TypeCode.UInt64: return checked((Int64)(UInt64)value);
                    case TypeCode.Single: return checked((Int64)(Single)value);
                    case TypeCode.Double: return checked((Int64)(Double)value);
                }
            }
            if (value is String s) {
                try {
                    return Int64.Parse(s, System.Globalization.NumberFormatInfo.InvariantInfo);
                } catch (FormatException ex) {
                    throw PythonOps.ValueError("{0}", ex.Message);
                }
            } else if (value is BigInteger bi) {
                return checked((Int64)bi);
            } else if (value is Extensible<BigInteger> ebi) {
                return checked((Int64)ebi.Value);
            } else if (value is Extensible<double> ed) {
                return checked((Int64)ed.Value);
            }
            throw PythonOps.TypeError("can't convert {0} to Int64", PythonOps.GetPythonTypeName(value));
        }

        #endregion

        #region Unary Operations

        [SpecialName]
        public static Int64 Plus(Int64 x) => x;

        [SpecialName]
        public static object Negate(Int64 x) {
            if (x == Int64.MinValue) return -(BigInteger)Int64.MinValue;
            else return (Int64)(-x);
        }

        [SpecialName]
        public static object Abs(Int64 x) {
            if (x < 0) {
                if (x == Int64.MinValue) return -(BigInteger)Int64.MinValue;
                else return (Int64)(-x);
            } else {
                return x;
            }
        }

        [SpecialName]
        public static Int64 OnesComplement(Int64 x) => (Int64)(~(x));

        public static bool __bool__(Int64 x) => (x != 0);

        public static string __repr__(Int64 x) => x.ToString(CultureInfo.InvariantCulture);

        public static Int64 __trunc__(Int64 x) => x;

        public static BigInteger __int__(Int64 x) => unchecked((BigInteger)x);

        public static BigInteger __index__(Int64 x) => unchecked((BigInteger)x);

        public static int __hash__(Int64 x) {
            if (x < 0) {
                if (x == long.MinValue) return -2;
                x = -x;
                var h = unchecked(-(int)((x >= int.MaxValue) ? (x % int.MaxValue) : x));
                if (h == -1) return -2;
                return h;
            }
            return unchecked((int)((x >= int.MaxValue) ? (x % int.MaxValue) : x));
        }

        #endregion

        #region Binary Operations - Arithmetic

        [SpecialName]
        public static object Add(Int64 x, Int64 y) {
            try {
                return (Int64)(checked(x + y));
            } catch (OverflowException) {
                return BigIntegerOps.Add((BigInteger)x, (BigInteger)y);
            }
        }

        [SpecialName]
        public static object Subtract(Int64 x, Int64 y) {
            try {
                return (Int64)(checked(x - y));
            } catch (OverflowException) {
                return BigIntegerOps.Subtract((BigInteger)x, (BigInteger)y);
            }
        }

        [SpecialName]
        public static object Multiply(Int64 x, Int64 y) {
            try {
                return (Int64)(checked(x * y));
            } catch (OverflowException) {
                return BigIntegerOps.Multiply((BigInteger)x, (BigInteger)y);
            }
        }

        [SpecialName]
        public static double TrueDivide(Int64 x, Int64 y) {
            return DoubleOps.TrueDivide((double)x, (double)y);
        }

        [SpecialName]
        public static object FloorDivide(Int64 x, Int64 y) {
            if (y == -1 && x == Int64.MinValue) {
                return -(BigInteger)Int64.MinValue;
            } else {
                return (Int64)MathUtils.FloorDivideUnchecked(x, y);
            }
        }

        [SpecialName]
        public static Int64 Mod(Int64 x, Int64 y) {
            return (Int64)BigIntegerOps.Mod((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static object Power(Int64 x, Int64 y) {
            return BigIntegerOps.Power((BigInteger)x, (BigInteger)y);
        }

        #endregion

        #region Binary Operations - Bitwise

        [SpecialName]
        public static object LeftShift(Int64 x, BigInteger y) {
            return BigIntegerOps.LeftShift((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static Int64 RightShift(Int64 x, BigInteger y) {
            return (Int64)BigIntegerOps.RightShift((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static Int64 BitwiseAnd(Int64 x, Int64 y) {
            return (Int64)(x & y);
        }

        [SpecialName]
        public static Int64 BitwiseOr(Int64 x, Int64 y) {
            return (Int64)(x | y);
        }

        [SpecialName]
        public static Int64 ExclusiveOr(Int64 x, Int64 y) {
            return (Int64)(x ^ y);
        }

        #endregion

        #region Binary Operations - Comparisons

        [SpecialName]
        public static bool LessThan(Int64 x, Int64 y) => x < y;
        [SpecialName]
        public static bool LessThanOrEqual(Int64 x, Int64 y) => x <= y;
        [SpecialName]
        public static bool GreaterThan(Int64 x, Int64 y) => x > y;
        [SpecialName]
        public static bool GreaterThanOrEqual(Int64 x, Int64 y) => x >= y;
        [SpecialName]
        public static bool Equals(Int64 x, Int64 y) => x == y;
        [SpecialName]
        public static bool NotEquals(Int64 x, Int64 y) => x != y;

        #endregion

        #region Conversion operators

        [SpecialName, ExplicitConversionMethod]
        public static SByte ConvertToSByte(Int64 x) {
            if (SByte.MinValue <= x && x <= SByte.MaxValue) {
                return (SByte)x;
            }
            throw Converter.CannotConvertOverflow("SByte", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static Byte ConvertToByte(Int64 x) {
            if (Byte.MinValue <= x && x <= Byte.MaxValue) {
                return (Byte)x;
            }
            throw Converter.CannotConvertOverflow("Byte", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static Int16 ConvertToInt16(Int64 x) {
            if (Int16.MinValue <= x && x <= Int16.MaxValue) {
                return (Int16)x;
            }
            throw Converter.CannotConvertOverflow("Int16", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static UInt16 ConvertToUInt16(Int64 x) {
            if (UInt16.MinValue <= x && x <= UInt16.MaxValue) {
                return (UInt16)x;
            }
            throw Converter.CannotConvertOverflow("UInt16", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static Int32 ConvertToInt32(Int64 x) {
            if (Int32.MinValue <= x && x <= Int32.MaxValue) {
                return (Int32)x;
            }
            throw Converter.CannotConvertOverflow("Int32", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static UInt32 ConvertToUInt32(Int64 x) {
            if (UInt32.MinValue <= x && x <= UInt32.MaxValue) {
                return (UInt32)x;
            }
            throw Converter.CannotConvertOverflow("UInt32", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static UInt64 ConvertToUInt64(Int64 x) {
            if (x >= 0) {
                return (UInt64)x;
            }
            throw Converter.CannotConvertOverflow("UInt64", x);
        }

        [SpecialName, ImplicitConversionMethod]
        public static Single ConvertToSingle(Int64 x) => (Single)x;

        [SpecialName, ImplicitConversionMethod]
        public static Double ConvertToDouble(Int64 x) => (Double)x;

        #endregion

        #region Public API - Numerics

        [PropertyMethod, SpecialName]
        public static Int64 Getreal(Int64 x) => x;

        [PropertyMethod, SpecialName]
        public static Int64 Getimag(Int64 x) => (Int64)0;

        public static Int64 conjugate(Int64 x) => x;


        [PropertyMethod, SpecialName]
        public static Int64 Getnumerator(Int64 x) => x;

        [PropertyMethod, SpecialName]
        public static Int64 Getdenominator(Int64 x) => (Int64)1;

        public static int bit_length(Int64 value) {
            return MathUtils.BitLength(value);
        }

        #endregion
    }

    public static partial class UInt64Ops {

        #region Constructors

        [StaticExtensionMethod]
        public static object __new__(PythonType cls) {
            return __new__(cls, default(UInt64));
        }

        [StaticExtensionMethod]
        public static object __new__(PythonType cls, object value) {
            if (cls != DynamicHelpers.GetPythonTypeFromType(typeof(UInt64))) {
                throw PythonOps.TypeError("UInt64.__new__: first argument must be UInt64 type.");
            }
            if (value is IConvertible valueConvertible) {
                switch (valueConvertible.GetTypeCode()) {
                    case TypeCode.Byte:   return checked((UInt64)(Byte)value);
                    case TypeCode.SByte:  return checked((UInt64)(SByte)value);
                    case TypeCode.Int16:  return checked((UInt64)(Int16)value);
                    case TypeCode.UInt16: return checked((UInt64)(UInt16)value);
                    case TypeCode.Int32:  return checked((UInt64)(Int32)value);
                    case TypeCode.UInt32: return checked((UInt64)(UInt32)value);
                    case TypeCode.Int64:  return checked((UInt64)(Int64)value);
                    case TypeCode.UInt64: return checked((UInt64)(UInt64)value);
                    case TypeCode.Single: return checked((UInt64)(Single)value);
                    case TypeCode.Double: return checked((UInt64)(Double)value);
                }
            }
            if (value is String s) {
                try {
                    return UInt64.Parse(s, System.Globalization.NumberFormatInfo.InvariantInfo);
                } catch (FormatException ex) {
                    throw PythonOps.ValueError("{0}", ex.Message);
                }
            } else if (value is BigInteger bi) {
                return checked((UInt64)bi);
            } else if (value is Extensible<BigInteger> ebi) {
                return checked((UInt64)ebi.Value);
            } else if (value is Extensible<double> ed) {
                return checked((UInt64)ed.Value);
            }
            throw PythonOps.TypeError("can't convert {0} to UInt64", PythonOps.GetPythonTypeName(value));
        }

        #endregion

        #region Unary Operations

        [SpecialName]
        public static UInt64 Plus(UInt64 x) => x;

        [SpecialName]
        public static object Negate(UInt64 x) => BigIntegerOps.Negate((BigInteger)x);

        [SpecialName]
        public static UInt64 Abs(UInt64 x) => x;

        [SpecialName]
        public static object OnesComplement(UInt64 x) => BigIntegerOps.OnesComplement((BigInteger)x);

        public static bool __bool__(UInt64 x) => (x != 0);

        public static string __repr__(UInt64 x) => x.ToString(CultureInfo.InvariantCulture);

        public static UInt64 __trunc__(UInt64 x) => x;

        public static BigInteger __int__(UInt64 x) => unchecked((BigInteger)x);

        public static BigInteger __index__(UInt64 x) => unchecked((BigInteger)x);

        public static int __hash__(UInt64 x) {
            return unchecked((int)((x >= int.MaxValue) ? (x % int.MaxValue) : x));
        }

        #endregion

        #region Binary Operations - Arithmetic

        [SpecialName]
        public static object Add(UInt64 x, UInt64 y) {
            try {
                return (UInt64)(checked(x + y));
            } catch (OverflowException) {
                return BigIntegerOps.Add((BigInteger)x, (BigInteger)y);
            }
        }

        [SpecialName]
        public static object Add(UInt64 x, BigInteger y) {
            return BigIntegerOps.Add((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static object Add(BigInteger x, UInt64 y) {
            return BigIntegerOps.Add((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static object Subtract(UInt64 x, UInt64 y) {
            try {
                return (UInt64)(checked(x - y));
            } catch (OverflowException) {
                return BigIntegerOps.Subtract((BigInteger)x, (BigInteger)y);
            }
        }

        [SpecialName]
        public static object Subtract(UInt64 x, BigInteger y) {
            return BigIntegerOps.Subtract((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static object Subtract(BigInteger x, UInt64 y) {
            return BigIntegerOps.Subtract((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static object Multiply(UInt64 x, UInt64 y) {
            try {
                return (UInt64)(checked(x * y));
            } catch (OverflowException) {
                return BigIntegerOps.Multiply((BigInteger)x, (BigInteger)y);
            }
        }

        [SpecialName]
        public static object Multiply(UInt64 x, BigInteger y) {
            return BigIntegerOps.Multiply((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static object Multiply(BigInteger x, UInt64 y) {
            return BigIntegerOps.Multiply((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static double TrueDivide(UInt64 x, UInt64 y) {
            return DoubleOps.TrueDivide((double)x, (double)y);
        }

        [SpecialName]
        public static double TrueDivide(UInt64 x, BigInteger y) {
            return BigIntegerOps.TrueDivide((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static double TrueDivide(BigInteger x, UInt64 y) {
            return BigIntegerOps.TrueDivide((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static UInt64 FloorDivide(UInt64 x, UInt64 y) {
            return (UInt64)(x / y);
        }

        [SpecialName]
        public static object FloorDivide(UInt64 x, BigInteger y) {
            return BigIntegerOps.FloorDivide((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static object FloorDivide(BigInteger x, UInt64 y) {
            return BigIntegerOps.FloorDivide((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static UInt64 Mod(UInt64 x, UInt64 y) {
            return (UInt64)(x % y);
        }

        [SpecialName]
        public static BigInteger Mod(UInt64 x, BigInteger y) {
            return BigIntegerOps.Mod((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static BigInteger Mod(BigInteger x, UInt64 y) {
            return BigIntegerOps.Mod((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static object Power(UInt64 x, UInt64 y) {
            return BigIntegerOps.Power((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static object Power(UInt64 x, BigInteger y) {
            return BigIntegerOps.Power((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static object Power(BigInteger x, UInt64 y) {
            return BigIntegerOps.Power((BigInteger)x, (BigInteger)y);
        }

        #endregion

        #region Binary Operations - Bitwise

        [SpecialName]
        public static object LeftShift(UInt64 x, BigInteger y) {
            return BigIntegerOps.LeftShift((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static UInt64 RightShift(UInt64 x, BigInteger y) {
            return (UInt64)BigIntegerOps.RightShift((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static UInt64 BitwiseAnd(UInt64 x, UInt64 y) {
            return (UInt64)(x & y);
        }

        [SpecialName]
        public static BigInteger BitwiseAnd(UInt64 x, BigInteger y) {
            return BigIntegerOps.BitwiseAnd((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static BigInteger BitwiseAnd(BigInteger x, UInt64 y) {
            return BigIntegerOps.BitwiseAnd((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static UInt64 BitwiseOr(UInt64 x, UInt64 y) {
            return (UInt64)(x | y);
        }

        [SpecialName]
        public static BigInteger BitwiseOr(UInt64 x, BigInteger y) {
            return BigIntegerOps.BitwiseOr((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static BigInteger BitwiseOr(BigInteger x, UInt64 y) {
            return BigIntegerOps.BitwiseOr((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static UInt64 ExclusiveOr(UInt64 x, UInt64 y) {
            return (UInt64)(x ^ y);
        }

        [SpecialName]
        public static BigInteger ExclusiveOr(UInt64 x, BigInteger y) {
            return BigIntegerOps.ExclusiveOr((BigInteger)x, (BigInteger)y);
        }

        [SpecialName]
        public static BigInteger ExclusiveOr(BigInteger x, UInt64 y) {
            return BigIntegerOps.ExclusiveOr((BigInteger)x, (BigInteger)y);
        }

        #endregion

        #region Binary Operations - Comparisons

        [SpecialName]
        public static bool LessThan(UInt64 x, UInt64 y) => x < y;
        [SpecialName]
        public static bool LessThan(UInt64 x, BigInteger y) => BigIntegerOps.LessThan((BigInteger)x, (BigInteger)y);
        [SpecialName]
        public static bool LessThanOrEqual(UInt64 x, UInt64 y) => x <= y;
        [SpecialName]
        public static bool LessThanOrEqual(UInt64 x, BigInteger y) => BigIntegerOps.LessThanOrEqual((BigInteger)x, (BigInteger)y);
        [SpecialName]
        public static bool GreaterThan(UInt64 x, UInt64 y) => x > y;
        [SpecialName]
        public static bool GreaterThan(UInt64 x, BigInteger y) => BigIntegerOps.GreaterThan((BigInteger)x, (BigInteger)y);
        [SpecialName]
        public static bool GreaterThanOrEqual(UInt64 x, UInt64 y) => x >= y;
        [SpecialName]
        public static bool GreaterThanOrEqual(UInt64 x, BigInteger y) => BigIntegerOps.GreaterThanOrEqual((BigInteger)x, (BigInteger)y);
        [SpecialName]
        public static bool Equals(UInt64 x, UInt64 y) => x == y;
        [SpecialName]
        public static bool Equals(UInt64 x, BigInteger y) => BigIntegerOps.Equals((BigInteger)x, (BigInteger)y);
        [SpecialName]
        public static bool NotEquals(UInt64 x, UInt64 y) => x != y;
        [SpecialName]
        public static bool NotEquals(UInt64 x, BigInteger y) => BigIntegerOps.NotEquals((BigInteger)x, (BigInteger)y);

        #endregion

        #region Conversion operators

        [SpecialName, ExplicitConversionMethod]
        public static SByte ConvertToSByte(UInt64 x) {
            if (x <= (UInt64)SByte.MaxValue) {
                return (SByte)x;
            }
            throw Converter.CannotConvertOverflow("SByte", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static Byte ConvertToByte(UInt64 x) {
            if (Byte.MinValue <= x && x <= Byte.MaxValue) {
                return (Byte)x;
            }
            throw Converter.CannotConvertOverflow("Byte", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static Int16 ConvertToInt16(UInt64 x) {
            if (x <= (UInt64)Int16.MaxValue) {
                return (Int16)x;
            }
            throw Converter.CannotConvertOverflow("Int16", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static UInt16 ConvertToUInt16(UInt64 x) {
            if (UInt16.MinValue <= x && x <= UInt16.MaxValue) {
                return (UInt16)x;
            }
            throw Converter.CannotConvertOverflow("UInt16", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static Int32 ConvertToInt32(UInt64 x) {
            if (x <= (UInt64)Int32.MaxValue) {
                return (Int32)x;
            }
            throw Converter.CannotConvertOverflow("Int32", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static UInt32 ConvertToUInt32(UInt64 x) {
            if (UInt32.MinValue <= x && x <= UInt32.MaxValue) {
                return (UInt32)x;
            }
            throw Converter.CannotConvertOverflow("UInt32", x);
        }

        [SpecialName, ExplicitConversionMethod]
        public static Int64 ConvertToInt64(UInt64 x) {
            if (x <= (UInt64)Int64.MaxValue) {
                return (Int64)x;
            }
            throw Converter.CannotConvertOverflow("Int64", x);
        }

        [SpecialName, ImplicitConversionMethod]
        public static Single ConvertToSingle(UInt64 x) => (Single)x;

        [SpecialName, ImplicitConversionMethod]
        public static Double ConvertToDouble(UInt64 x) => (Double)x;

        #endregion

        #region Public API - Numerics

        [PropertyMethod, SpecialName]
        public static UInt64 Getreal(UInt64 x) => x;

        [PropertyMethod, SpecialName]
        public static UInt64 Getimag(UInt64 x) => (UInt64)0;

        public static UInt64 conjugate(UInt64 x) => x;


        [PropertyMethod, SpecialName]
        public static UInt64 Getnumerator(UInt64 x) => x;

        [PropertyMethod, SpecialName]
        public static UInt64 Getdenominator(UInt64 x) => (UInt64)1;

        public static int bit_length(UInt64 value) {
            return MathUtils.BitLengthUnsigned(value);
        }

        #endregion
    }


    // *** END GENERATED CODE ***

    #endregion
}
